package scuts.core;

import scuts.core.macros.F;
import scuts.core.Fold;

class SumIterableInt {
	public static function sum (iter:Iterable<Int>):Int
	{
		return SumIteratorInt.sum(iter.iterator());
	}
}

class SumIterableFloat {
	public static function sumFloat <A>(iter:Iterable<Float>):Float
	{
		return SumIteratorFloat.sumFloat(iter.iterator());
	}
}

class SumIteratorInt {
	public static function sum (iter:Iterator<Int>):Int
	{
		return FoldIterator.foldLeft(iter, F.n(a,v = a + v), 0);
	}
}

class SumIteratorFloat {
	public static function sumFloat (iter:Iterator<Float>):Float
	{
		return FoldIterator.foldLeft(iter, function (a,v) return a + v, 0.0);
	}
}

class SumIterable {
	public static function sum <A>(iter:Iterable<A>, f:A->Int):Int
	{
		return SumIterator.sum(iter.iterator(), f);
	}
	public static function sumFloat <A>(iter:Iterable<A>, f:A->Float):Float
	{
		return SumIterator.sumFloat(iter.iterator(), f);
	}
}

class SumIterator {
	public static function sum <A>(iter:Iterator<A>, f:A->Int):Int
	{
		return FoldIterator.foldLeft(iter, F.n(a,v = a + f(v)), 0);
	}
	public static function sumFloat <A>(iter:Iterator<A>, f:A->Float):Float
	{
		return FoldIterator.foldLeft(iter, F.n(a,v = a + f(v)), 0);
	}
}